using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using FU.Capstones.IMS.Web.Common;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.DataContracts;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.EventArgs;
using FU.Capstones.IMS.Web.Silverlight.Models;
using Microsoft.Practices.Prism.Commands;
using Navigation.Silverlight;

namespace FU.Capstones.IMS.Web.Silverlight.ViewModels
{
    public class EmployeeDetailViewModel : ViewModelBase
    {
        public EmployeeDetailViewModel()
        {
            Model = new EmployeeDetailModel();
            ((EmployeeDetailModel)Model).GetSingleEmployeeCompleted += DoGetSingleEmployeeCompleted;
            ((EmployeeDetailModel)Model).InsertEmployeeCompleted += DoInsertEmployeeCompleted;
            ((EmployeeDetailModel)Model).UpdateEmployeeCompleted += DoUpdateEmployeeCompleted;
            ((EmployeeDetailModel)Model).GetRoleCollectionCommpleted += DoGetRoleCollectionCommpleted;
            ((EmployeeDetailModel)Model).GetEmploymentTypeCollectionCompleted += DoGetEmploymentTypeCollectionCompleted;
            ((EmployeeDetailModel)Model).GetAuthorizationCollectionCompleted += GetAuthorizationCollectionCompleted;
            ((EmployeeDetailModel)Model).ResetPasswordCompleted += ResetPasswordCompleted;
            ((EmployeeDetailModel)Model).CheckIfUsernameExistsCompleted += CheckIfUsernameExistsCompleted;
            
            IsFirstLoaded = false;
            ServiceCallCounter += ((EmployeeDetailModel)Model).GetRoleCollectionAsync();
            ServiceCallCounter += ((EmployeeDetailModel)Model).GetEmploymentTypeCollectionAsync();
            ServiceCallCounter += ((EmployeeDetailModel) Model).GetAuthorizationCollectionAsync();

            MessageVisibility = Visibility.Collapsed;
            ErrorMessageVisibility = Visibility.Collapsed;

            CanEditOrAdd = CurrentUser.CanEditEmployee;
            if (!CanEditOrAdd)
                CanEditOrAdd = CurrentUser.CanAddEmployee;
            CanAdd = CurrentUser.CanAddEmployee;
        }

        #region Do Completed Methods

        void CheckIfUsernameExistsCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(!e.Result.IsSuccessful);
                if (!e.Result.IsSuccessful)
                {
                   ServiceCallCounter += ((EmployeeDetailModel)Model).InsertEmployeeAsync(Employee);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void ResetPasswordCompleted(object sender, FeedbackCompletedEventArgs e)
        {

            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void GetAuthorizationCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Authorization> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    AuthorizationCollection = e.Result.Data;
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetEmploymentTypeCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<EmploymentType> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    EmploymentTypeCollection = e.Result.Data;
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetRoleCollectionCommpleted(object sender, CollectionFeedbackCompletedEventArgs<Role> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    RoleCollection = e.Result.Data;
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoUpdateEmployeeCompleted(object sender, FeedbackCompletedEventArgs e)
        {

            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    AuthorizationCollection = new ObservableCollection<Authorization>(AuthorizationCollection.OrderByDescending(au => au.IsSelected));
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoInsertEmployeeCompleted(object sender, SingleFeedbackCompletedEventArgs<int> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    IsCreateNew = false;
                    Employee.EmployeeID = e.Result.Data;
                    AuthorizationCollection = new ObservableCollection<Authorization>(AuthorizationCollection.OrderByDescending(au => au.IsSelected));
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetSingleEmployeeCompleted(object sender, SingleFeedbackCompletedEventArgs<Employee> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    //Asign the data from database
                    Employee = new Employee()
                                   {
                                       Address = e.Result.Data.Address,
                                       DateOfBirth = e.Result.Data.DateOfBirth,
                                       Description = e.Result.Data.Description,
                                       Email = e.Result.Data.Email,
                                       EmployeeID = e.Result.Data.EmployeeID,
                                       EmploymentType = e.Result.Data.EmploymentType,
                                       FullName = e.Result.Data.FullName,
                                       Gender = e.Result.Data.Gender,
                                       IdentityCardNumber = e.Result.Data.IdentityCardNumber,
                                       JoinedDate = e.Result.Data.JoinedDate,
                                       MobileNumber = e.Result.Data.MobileNumber,
                                       PhoneNumber = e.Result.Data.PhoneNumber,
                                       Role = e.Result.Data.Role,
                                       Username =  e.Result.Data.Username,
                                       AuthorizationCollection = e.Result.Data.AuthorizationCollection
                                   };
                    Backup();

                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        #endregion

        #region Commands

        #region SaveCommand

        private DelegateCommand<object> saveCommand;
        public DelegateCommand<object> SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new DelegateCommand<object>(DoSaveCommand);
                return saveCommand;
            }
        }

        private void DoSaveCommand(object obj)
        {
            Employee.ValidateAll();
            if (!Employee.HasErrors)
            {
                if (isCreateNew)
                    ServiceCallCounter += ((EmployeeDetailModel)Model).CheckIfUsernameExistsAsync(Employee.Username);
                else
                {
                    ServiceCallCounter += ((EmployeeDetailModel)Model).UpdateEmployeeAsync(Employee);
                }
            }
            else
            {
                Message = WebConstants.InvalidInputDataMessage;
                SetMessageVisibility(false);
            }
        }

        #endregion

        #region CancelCommand

        private DelegateCommand<object> cancelCommand;
        public DelegateCommand<object> CancelCommand
        {
            get
            {
                if (cancelCommand == null)
                    cancelCommand = new DelegateCommand<object>(DoCancelCommand);
                return cancelCommand;
            }
        }

        private void DoCancelCommand(object obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.EmployeeList);
        }

        #endregion

        #region ResetCommand

        private DelegateCommand<object> resetCommand;
        public DelegateCommand<object> ResetCommand
        {
            get
            {
                if (resetCommand == null)
                    resetCommand = new DelegateCommand<object>(DoResetCommand);
                return resetCommand;
            }
        }

        private void DoResetCommand(object obj)
        {
            if (isCreateNew)
                Employee = new Employee();
            else
            {
                Employee = employeeTemp;
                MappWithCollection();
                Backup();
            }
        }

        #endregion

        #region ResetPasswordCommand

        private DelegateCommand<object> resetPasswordCommand;

        public DelegateCommand<object> ResetPasswordCommand
        {
            get
            {
                if (resetPasswordCommand == null)
                    resetPasswordCommand = new DelegateCommand<object>(DoResetPasswordCommand);
                return resetPasswordCommand;
            }
        }

        private void DoResetPasswordCommand(object obj)
        {
            if (!isCreateNew)
            {
                ServiceCallCounter += ((EmployeeDetailModel) Model).ResetPasswordAsync(new Account(){EmployeeID = Employee.EmployeeID, Username = Employee.Username});
            }
        }

        #endregion

        #region SelectCommand

        private DelegateCommand<int?> selectCommand;

        public DelegateCommand<int?> SelectCommand
        {
            get
            {
                if (selectCommand == null)
                    selectCommand = new DelegateCommand<int?>(DoSelectCommand);
                return selectCommand;
            }
        }

        private void DoSelectCommand(int? obj)
        {
            if (obj.HasValue && Employee != null)
            {
                if (Employee.AuthorizationCollection == null)
                    Employee.AuthorizationCollection = new ObservableCollection<int>();
                Authorization temp = AuthorizationCollection.FirstOrDefault(x => x.AuthorizationID == obj.Value);
                if (temp != null)
                {
                    if (temp.IsSelected)
                    {
                        Employee.AuthorizationCollection.Add(temp.AuthorizationID);
                    }
                    else
                    {
                        Employee.AuthorizationCollection.Remove(temp.AuthorizationID);
                    }
                }
            }
        }

        #endregion

        #region SelectCommand

        private DelegateCommand<object> selectRoleCommand;

        public DelegateCommand<object> SelectRoleCommand
        {
            get
            {
                if (selectRoleCommand == null)
                    selectRoleCommand = new DelegateCommand<object>(DoSelectRoleCommand);
                return selectRoleCommand;
            }
        }

        private void DoSelectRoleCommand(object obj)
        {
            //if (Employee.Role!=null && !IsFirstLoaded)
            //{
            //    bool isChanged = (Employee.AuthorizationCollection.Count != Employee.Role.AuthorizationCollection.Count);
            //    if (!isChanged)
            //    {
            //        string stemp1 = Employee.AuthorizationCollection.OrderBy(x => x).ToString();
            //        string stemp2 = Employee.Role.AuthorizationCollection.OrderBy(x => x).ToString();
            //        isChanged = string.Compare(stemp2, stemp1, StringComparison.OrdinalIgnoreCase) != 0;
            //    }
            //    if (isChanged)
            //    {
            //        ChangeRoleConfirmationPopup popup = new ChangeRoleConfirmationPopup();
            //        popup.Show();
            //        popup.Closed += (sender, e) =>
            //                            {
            //                                if (popup.DialogResult.HasValue && popup.DialogResult.Value)
            //                                {
            //                                    Employee.AuthorizationCollection = Employee.Role.AuthorizationCollection;

            //                                    if (Employee.AuthorizationCollection != null && AuthorizationCollection != null)
            //                                    {
            //                                        int upper = Employee.AuthorizationCollection.Count;
            //                                        for (int i = 0; i < upper; i++)
            //                                        {
            //                                            Authorization au = AuthorizationCollection.FirstOrDefault(x => x.AuthorizationID == Employee.AuthorizationCollection[i]);
            //                                            if (au != null)
            //                                                au.IsSelected = true;
            //                                        }

            //                                        AuthorizationCollection = new ObservableCollection<Authorization>(AuthorizationCollection.OrderByDescending(au => au.IsSelected));
            //                                    }
            //                                }
            //                            };
            //    }
            //}
        }

        #endregion

        #endregion

        #region Binding Properties

        private Employee employee;
        public Employee Employee
        {
            get { return employee; }
            set
            {
                if (!ReferenceEquals(employee, value))
                {
                    employee = value;
                    RaisePropertyChanged(() => Employee);
                }
            }
        }

        private ObservableCollection<Role> roleCollection;
        public ObservableCollection<Role> RoleCollection
        {
            get { return roleCollection; }
            set
            {
                if (!ReferenceEquals(roleCollection, value))
                {
                    roleCollection = value;
                    RaisePropertyChanged(() => RoleCollection);
                }
            }
        }

        private ObservableCollection<EmploymentType> eTypeCollection;
        public ObservableCollection<EmploymentType> EmploymentTypeCollection
        {
            get { return eTypeCollection; }
            set
            {
                if (!ReferenceEquals(eTypeCollection, value))
                {
                    eTypeCollection = value;
                    RaisePropertyChanged(() => EmploymentTypeCollection);
                }
            }
        }

        private ObservableCollection<Authorization> authorizationCollection;
        public ObservableCollection<Authorization> AuthorizationCollection
        {
            get { return authorizationCollection; }
            set
            {
                if (!ReferenceEquals(authorizationCollection, value))
                {
                    authorizationCollection = value;
                    RaisePropertyChanged(() => AuthorizationCollection);
                }
            }
        }
        
        public ObservableCollection<string> GenderCollection
        {
            get {return new ObservableCollection<string>(){"Nam", "Nữ"};}
        }

        private bool isCreateNew;
        public bool IsCreateNew
        {
            get { return isCreateNew; }
            set
            {
                if (isCreateNew != value)
                {
                    isCreateNew = value;
                    RaisePropertyChanged(() => IsCreateNew);
                }
            }
        }

        #endregion

        #region Fields

        private Employee employeeTemp;

        #endregion

        #region Implementation of INavigationAware

        public override void OnNavigate(object extraData)
        {
            NavigationData data = (NavigationData) extraData;
            if (data != null)
            {
                if (data.NavigationUri.CompareTo(WebConstants.NavigationPages.EmployeeList)==0)
                {
                    int? objID = (int?) data.Data;
                    IsCreateNew = (objID.HasValue == false || objID.Value == 0);
                    if (!isCreateNew)
                    {
                        IsFirstLoaded = true;
                        ServiceCallCounter += ((EmployeeDetailModel) Model).GetSingleEmployeeAsync(objID.Value);
                    }
                    else
                    {
                        Employee = new Employee()
                                        {
                                            AuthorizationCollection = new ObservableCollection<int>()
                                        };
                    }
                    Message = "Đang kết nối tới máy chủ...";
                }
            }
        }

        public override void OnLeave()
        {
            //throw new NotImplementedException();
        }

        #endregion

        protected override void HandleLoadingCompleted()
        {
            if (ServiceCallCounter == 0 && !isCreateNew && IsFirstLoaded)
            {
                MappWithCollection();
                IsFirstLoaded = false;
            }
        }

        private void Backup()
        {
            if (Employee != null)
            {
                employeeTemp = new Employee()
                {
                    Address = Employee.Address,
                    Username =  Employee.Username,
                    DateOfBirth = Employee.DateOfBirth,
                    Description = Employee.Description,
                    Email = Employee.Email,
                    EmployeeID = Employee.EmployeeID,
                    EmploymentType =
                        new EmploymentType() { EmploymentTypeID = Employee.EmploymentType == null ? 0 : Employee.EmploymentType.EmploymentTypeID },
                    Role = new Role() { RoleID = Employee.Role == null ? 0 : Employee.Role.RoleID },
                    FullName = Employee.FullName,
                    Gender = Employee.Gender,
                    IdentityCardNumber = Employee.IdentityCardNumber,
                    PhoneNumber = Employee.PhoneNumber,
                    MobileNumber = Employee.MobileNumber,
                    JoinedDate = Employee.JoinedDate
                };
                if (Employee.AuthorizationCollection != null)
                {
                    employeeTemp.AuthorizationCollection = new ObservableCollection<int>();
                    foreach(int auID in Employee.AuthorizationCollection)
                    {
                        employeeTemp.AuthorizationCollection.Add(auID);
                    }
                }
            }
        }

        private void MappWithCollection()
        {
            if (!isCreateNew)
            {
                if (Employee.EmploymentType != null && EmploymentTypeCollection != null)
                {
                    EmploymentType etemp = EmploymentTypeCollection.FirstOrDefault( eType => eType.EmploymentTypeID == Employee.EmploymentType.EmploymentTypeID);
                    if (etemp == null)
                    {
                        EmploymentTypeCollection.Add(Employee.EmploymentType);
                        Employee.EmploymentType = new EmploymentType(){EmploymentTypeID = Employee.EmploymentType.EmploymentTypeID};
                        etemp =EmploymentTypeCollection.FirstOrDefault(eType => eType.EmploymentTypeID == Employee.EmploymentType.EmploymentTypeID);
                    }
                    Employee.EmploymentType = etemp;
                }
                if (Employee.AuthorizationCollection != null && AuthorizationCollection != null)
                {
                    int upper = Employee.AuthorizationCollection.Count;
                    for (int i = 0; i < upper; i++)
                    {
                        Authorization au = AuthorizationCollection.FirstOrDefault(x => x.AuthorizationID == Employee.AuthorizationCollection[i]);
                        if (au != null)
                            au.IsSelected = true;
                    }

                    AuthorizationCollection = new ObservableCollection<Authorization>(AuthorizationCollection.OrderByDescending(au=>au.IsSelected));
                }
                if (Employee.Role != null && RoleCollection != null)
                {
                    Role rtemp = RoleCollection.FirstOrDefault(role => role.RoleID == Employee.Role.RoleID);
                    if (rtemp == null)
                    {
                        RoleCollection.Add(Employee.Role);
                        Employee.Role = new Role() { RoleID = Employee.Role.RoleID };
                        rtemp = RoleCollection.FirstOrDefault(eType => eType.RoleID == Employee.Role.RoleID);
                    }
                    Employee.Role = rtemp;
                }
                if (!string.IsNullOrEmpty(Employee.Gender) && GenderCollection != null)
                {
                    int upper = GenderCollection.Count;
                    for (int i = 0; i < upper; i++)
                    {
                        Employee.Gender = GenderCollection.FirstOrDefault(x => string.Compare(Employee.Gender, x)==0);
                    }
                }
            }
        }
    }
}

